import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// 支持使用 /**/进行单行或多行注释，不支持使用 // 进行单行注释
// 键（标签）/值 内容可以使用中英文，不要使用引号大括号和中括号
// 键可以带有不同类型的值，也会被解析出来
// 空数组不会解析，也不会解压缩
// 空对象可以被解析和解压缩
public class JsonUtil {
    //region 初始化
    public JsonUtil(String jsonStr)
    {
        this.jsonStr=jsonStr;
        Reduce();
        Init();
    }
    private void Reduce() //json 压缩
    {
        String patternStr = "";
        Pattern pattern = null;
        Matcher matcher = null;
        //region ******************* 移除多行注释 ***************************
        // /\*[\s\S]*?\*/
        // 移除多行注释
        patternStr = "/\\*[\\s\\S]*?\\*/";
        pattern = Pattern.compile(patternStr);
        matcher = pattern.matcher(jsonStr);
        if (matcher.find())//匹配成功
        {
            jsonStr = matcher.replaceAll("");
        }
        //endregion
        //region ******************* 移除空白字符 ***************************
        // Json 压缩

        // "[\s\S]*?"
        // 匹配引号及其内容
        // \s
        // 匹配空白字符
        int start = 0;
        int end = 0;
        StringBuffer sb = new StringBuffer();
        List<Integer> starts = new ArrayList<>();
        List<Integer> ends = new ArrayList<>();
        patternStr = "\"[\\s\\S]*?\"";
        pattern = Pattern.compile(patternStr);
        matcher = pattern.matcher(jsonStr);
        while (matcher.find()) {
            end = matcher.start();
            starts.add(start);
            ends.add(end);
            start = matcher.end();
        }
        end = jsonStr.length();
        starts.add(start);
        ends.add(end);
        //
        patternStr = "\\s";
        pattern = Pattern.compile(patternStr);
        for (int i = starts.size() - 1; i >= 0; i--) {
            matcher = pattern.matcher(jsonStr);
            matcher.region(starts.get(i), ends.get(i));
            sb.delete(0, sb.length());//清空缓存
            while (matcher.find()) {
                matcher.appendReplacement(sb, "");
            }
            matcher.appendTail(sb);
            jsonStr = sb.toString() + jsonStr.substring(ends.get(i), jsonStr.length());
        }
        //endregion
    }
    private void Init() //解析Json
    {
        jsonObj=new JsonElement();
        jsonObj.rootTag="";
        jsonObj.parentElement=null;
        parsingBody(jsonObj,jsonStr);
    }
    //endregion
    //region 属性
    private String jsonStr;
    public JsonElement jsonObj;
    //endregion
    //region Util
    private static void print(String msg)
    {
        Log.d("JsonUtil:", msg);
    }

    public String toString() //将 jsonObj 转化成 字符串
    {
        return JsonElementToString(jsonObj);
    }
    private String JsonElementToString(JsonElement jsonElement)
    {
        String _JsonStr="{";
        int count=0;

        //region 所有bool键值
        HashMap<String,Boolean> boolmap=jsonElement.boolValue;
        for(String k : boolmap.keySet())
        {
            _JsonStr+="\""+k+"\":"+boolmap.get(k);
            if(++count!=boolmap.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有int键值
        HashMap<String, Integer> intmap=jsonElement.intValue;
        if(intmap.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : intmap.keySet())
        {
            _JsonStr+="\""+k+"\":"+intmap.get(k);
            if(++count!=intmap.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有浮点键值
        HashMap<String, Double> floatmap=jsonElement.doubleValue;
        if(floatmap.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : floatmap.keySet())
        {
            _JsonStr+="\""+k+"\":"+floatmap.get(k);
            if(++count!=floatmap.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有字符串键值
        HashMap<String, String> stringmap=jsonElement.stringValue;
        if(stringmap.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : stringmap.keySet())
        {
            _JsonStr+="\""+k+"\":\""+stringmap.get(k)+"\"";
            if(++count!=stringmap.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有JsonElement键值
        HashMap<String, JsonElement> jsonElementmap=jsonElement.jsonValue;
        if(jsonElementmap.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k:jsonElementmap.keySet())
        {
            _JsonStr+="\""+k+"\":"+JsonElementToString(jsonElementmap.get(k));
            if(++count!=jsonElementmap.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion

        //region 所有bool数组键值
        HashMap<String, List<Boolean>> boolmaps=jsonElement.boolsValue;
        if(boolmaps.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : boolmaps.keySet())
        {
            List<Boolean> bools=boolmaps.get(k);
            String boolStr="";
            for(int i=0;i<bools.size();i++)
            {
                boolStr+=bools.get(i);
                if(i<bools.size()-1)
                {
                    boolStr+=",";
                }
            }
            _JsonStr+="\""+k+"\":["+boolStr+"]";
            if(++count!=boolmaps.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有int数组键值
        HashMap<String, List<Integer>> intmaps=jsonElement.intsValue;
        if(intmaps.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : intmaps.keySet())
        {
            List<Integer> ints=intmaps.get(k);
            String intStr="";
            for(int i=0;i<ints.size();i++)
            {
                intStr+=ints.get(i);
                if(i<ints.size()-1)
                {
                    intStr+=",";
                }
            }
            _JsonStr+="\""+k+"\":["+intStr+"]";
            if(++count!=intmaps.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有浮点数组键值
        HashMap<String, List<Double>> floatmaps=jsonElement.doublesValue;
        if(floatmaps.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : floatmaps.keySet())
        {
            List<Double> floats=floatmaps.get(k);
            String floatStr="";
            for(int i=0;i<floats.size();i++)
            {
                floatStr+=floats.get(i);
                if(i<floats.size()-1)
                {
                    floatStr+=",";
                }
            }
            _JsonStr+="\""+k+"\":["+floatStr+"]";
            if(++count!=floatmaps.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有字符串数组键值
        HashMap<String, List<String>> stringmaps=jsonElement.stringsValue;
        if(stringmaps.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k : stringmaps.keySet())
        {
            List<String> strings=stringmaps.get(k);
            String stringStr="";
            for(int i=0;i<strings.size();i++)
            {
                stringStr+="\""+strings.get(i)+"\"";
                if(i<strings.size()-1)
                {
                    stringStr+=",";
                }
            }
            _JsonStr+="\""+k+"\":["+stringStr+"]";
            if(++count!=stringmaps.size())
            {
                _JsonStr+=",";
            }
        }
        count=0;
        //endregion
        //region 所有JsonElement数组键值
        HashMap<String, List<JsonElement>> jsonElementmaps=jsonElement.jsonsValue;
        if(jsonElementmaps.size()>0&&_JsonStr.length()>6)
        {
            _JsonStr+=",";
        }
        for(String k:jsonElementmaps.keySet())
        {
            List<JsonElement> jsonElements=jsonElementmaps.get(k);
            String jsonElementStr="";
            for(int i=0;i<jsonElements.size();i++)
            {
                jsonElementStr+=JsonElementToString(jsonElements.get(i));
                if(i<jsonElements.size()-1)
                {
                    jsonElementStr+=",";
                }
            }
            _JsonStr+="\""+k+"\":["+jsonElementStr+"]";
            if(++count!=jsonElementmaps.size())
            {
                _JsonStr+=",";
            }
        }
        //endregion

        _JsonStr+="}";
        return _JsonStr;
    };
    //endregion
    //region 内部解析
    // _json : json 格式字符串
    // pos   : 节点在_json 位置
    // return： 返回所在位置的层级。1：表示顶级层级（根节点），2：表示二级层级；3：表示三级层级；以此类推......(具体问题具体分析)
    private int NodeHierarchyNum(String _JsonStr, int pos) {
        _JsonStr = _JsonStr.substring(0, pos);
        int braceL = 0;   // 左括号数量
        int braceR = 0;   // 右括号数量
        //region ******************* 移除引号内容 ***************************
        // "[\s\S]*?"
        String patternStr = "\"[\\s\\S]*?\"";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        _JsonStr = matcher.replaceAll("");
        //endregion
        //region ******************* 左右括号计数 ***************************
        patternStr = "\\{";
        pattern = Pattern.compile(patternStr);
        matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            braceL++;
        }
        patternStr = "\\}";
        pattern = Pattern.compile(patternStr);
        matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            braceR++;
        }
        //endregion
        return braceL - braceR;
    }

    //region 数组
    private HashMap<String, List<Boolean>> getBoolMap(String _JsonStr)// 获取 节点下的所有bool数组集合
    {
        // "([^,"\[\]\{\}]+?)":\[(true|,|false)+?](?=(,|}))
        // 匹配 "BoolAray":[true,true,false,true,true,true],
        // BoolAray true,true,false,true,true,true
        HashMap<String, List<Boolean>> listHashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\\[(true|,|false)+?](?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                String mStr=matcher.group();
                String tag= matcher.group(1);
                String body= mStr.substring(4+tag.length(),mStr.length()-1);
                List<Boolean> booleans=new ArrayList<>();
                String[] strings=body.split(",");
                for(int i=0;i< strings.length;i++)
                {
                    booleans.add(Boolean.valueOf(strings[i]));
                }
                listHashMap.putIfAbsent(tag,booleans);
            }
        }
        return listHashMap;
    }
    private HashMap<String, List<Integer>> getIntMap(String _JsonStr)// 获取 节点下的所有整数数组集合
    {
        // "([^,"\[\]\{\}]+?)":\[(\d|,)+?](?=(,|}))
        // 匹配 "IntArray":[100,5,6,9,8,7,3,6,4,2]
        // IntArray 100,5,6,9,8,7,3,6,4,2
        HashMap<String, List<Integer>> listHashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\\[(\\d|,)+?](?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                String mStr=matcher.group();
                String tag= matcher.group(1);
                String body= mStr.substring(4+tag.length(),mStr.length()-1);
                List<Integer> integers=new ArrayList<>();
                String[] strings=body.split(",");
                for(int i=0;i< strings.length;i++)
                {
                    integers.add(Integer.valueOf(strings[i]));
                }
                listHashMap.putIfAbsent(tag,integers);
            }
        }
        return listHashMap;
    }
    private HashMap<String, List<Double>> getDoubleMap(String _JsonStr)// 获取 节点下的所有浮点数组集合
    {
        // "([^,"\[\]\{\}]+?)":\[(\d+?\.\d+?|,)+?](?=(,|}))
        // 匹配 "FloatArray":[0.1,0.2,0.6,0.6,0.8,0.8,10.65],
        // FloatArray 0.1,0.2,0.6,0.6,0.8,0.8,10.65
        HashMap<String, List<Double>> listHashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\\[(\\d+?\\.\\d+?|,)+?](?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                String mStr=matcher.group();
                String tag= matcher.group(1);
                String body= mStr.substring(4+tag.length(),mStr.length()-1);
                List<Double> integers=new ArrayList<>();
                String[] strings=body.split(",");
                for(int i=0;i< strings.length;i++)
                {
                    integers.add(Double.valueOf(strings[i]));
                }
                listHashMap.putIfAbsent(tag,integers);
            }
        }
        return listHashMap;
    }
    private HashMap<String, List<String>> getStringMap(String _JsonStr)// 获取 节点下的所有字符串数组集合
    {
        // "([^,"\[\]\{\}]+?)":\[("[\w\W]+?"|,)+?](?=(,|}))
        // 匹配 "StringArray":["1","fdasfasdfs","发大水发多少覆盖"]
        // StringArray "1","fdasfasdfs","发大水发多少覆盖"
        HashMap<String, List<String>> listHashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\\[(\"[\\w\\W]+?\"|,)+?](?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                String mStr=matcher.group();
                String tag= matcher.group(1);
                String body= mStr.substring(5+tag.length(),mStr.length()-2);
                List<String> integers=new ArrayList<>();
                String[] strings=body.split("\",\"");
                for(int i=0;i< strings.length;i++)
                {
                    integers.add(strings[i]);
                }
                listHashMap.putIfAbsent(tag,integers);
            }
        }
        return listHashMap;
    }
    private HashMap<String, List<String>> getJsonArrays(String _jsonStr)// 获取  Json对象数组
    {
        // "([^,"\[\]\{\}]+?)":\[{
        // 匹配对象开头
        // ](?=(,|}))
        // 匹配对象结束位置
        HashMap<String, List<String>> listHashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\\[\\{";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_jsonStr);
        while(matcher.find())
        {
            if(NodeHierarchyNum(_jsonStr,matcher.start())==1)//在第一层级也就是根节点的子节点
            {
                String nextStr=_jsonStr.substring(matcher.start());
                String ps="\\](?=(,|\\}))";
                Pattern p=Pattern.compile(ps);
                Matcher m=p.matcher(nextStr);
                while (m.find())
                {
                    if(NodeHierarchyNum(nextStr,m.end())==0)
                    {
                        String tag=matcher.group(1);
                        String body=nextStr.substring(tag.length()+4,m.end()-1);
                        List<String> list=new ArrayList<>();
                        String[] strings=body.split("(?<=\\}),(?=\\{)");
                        for(int i=0;i< strings.length;i++)
                        {
                            list.add(strings[i]);
                        }
                        listHashMap.putIfAbsent(tag,list);
                        _jsonStr=_jsonStr.substring(0, matcher.start())+nextStr.substring(m.end());
                        matcher = pattern.matcher(_jsonStr);
                        break;
                    }
                }
            }
        }
        return listHashMap;
    }

    //endregion
    //region  数值
    private HashMap<String, Boolean> getBools(String _JsonStr)// 获取 节点下的所有bool类型的集合
    {
        // "([^,"\[\]\{\}]+?)":(true|false)(?=(,|}))
        // "Bool":false,
        // 匹配上面的 Bool false
        HashMap<String, Boolean> hashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":(true|false)(?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                hashMap.putIfAbsent(matcher.group(1), Boolean.valueOf(matcher.group(2)));
            }
        }
        return hashMap;
    }
    private HashMap<String, Integer> getInts(String _JsonStr)// 获取 节点下的所有整数类型的集合
    {
        // "([^,"\[\]\{\}]+?)":([0-9]+)(?=(,|}))
        // "Int":11,
        // 匹配上面的 Int 11
        HashMap<String, Integer> hashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":([0-9]+)(?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                hashMap.putIfAbsent(matcher.group(1), Integer.valueOf(matcher.group(2)));
            }
        }
        return hashMap;
    }
    private HashMap<String, Double> getDoubles(String _JsonStr)// 获取 节点下的所有浮点类型的集合
    {
        // "([^,"\[\]\{\}]+?)":(\d+\.\d+)(?=(,|}))
        // "Float":"12656.501",
        // 匹配上面的 12656.501
        HashMap<String, Double> hashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":(\\d+\\.\\d+)(?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                hashMap.putIfAbsent(matcher.group(1), Double.valueOf(matcher.group(2)));
            }
        }
        return hashMap;
    }
    private HashMap<String, String> getStringss(String _JsonStr)// 获取 节点下的所有字符串类型的集合
    {
        // "([^,"\[\]\{\}]+?)":"([\w\W]*?)"(?=(,|}))
        // "String":"小强",
        // 匹配上面的 String 小强
        HashMap<String, String> hashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\"([\\w\\W]*?)\"(?=(,|\\}))";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_JsonStr);
        while (matcher.find()) {
            if (NodeHierarchyNum(_JsonStr, matcher.start()) == 1) {
                hashMap.putIfAbsent(matcher.group(1), matcher.group(2));
            }
        }
        return hashMap;
    }
    private HashMap<String, String> getJsonObjs(String _jsonStr)// 获取  所有子节点对象
    {
        // "([^,"\[\]\{\}]+?)":{
        // 匹配对象开头
        // }(?=(,|}))
        // 匹配对象结束位置
        HashMap<String, String> hashMap=new HashMap<>();
        String patternStr = "\"([^,\"\\[\\]\\{\\}]+?)\":\\{";
        Pattern pattern = Pattern.compile(patternStr);
        Matcher matcher = pattern.matcher(_jsonStr);
        while(matcher.find())
        {
            if(NodeHierarchyNum(_jsonStr,matcher.start())==1)//在第一层级也就是根节点的子节点
            {
                String nextStr=_jsonStr.substring(matcher.start());
                String ps="\\}(?=(,|\\}))";
                Pattern p=Pattern.compile(ps);
                Matcher m=p.matcher(nextStr);
                while (m.find())
                {
                    if(NodeHierarchyNum(nextStr,m.end())==0)
                    {
                        String tag=matcher.group(1);
                        String body=nextStr.substring(tag.length()+3,m.end());
                        hashMap.putIfAbsent(tag,body);
                        _jsonStr=_jsonStr.substring(0, matcher.start())+nextStr.substring(m.end());
                        matcher = pattern.matcher(_jsonStr);
                        break;
                    }
                }
            }
        }
        return hashMap;
    }
    //endregion
    private JsonElement parsingBody(JsonElement jsonElement,String _JsonStr)//解析json
    {
        jsonElement.boolValue=getBools(_JsonStr);
        jsonElement.intValue=getInts(_JsonStr);
        jsonElement.doubleValue=getDoubles(_JsonStr);
        jsonElement.stringValue=getStringss(_JsonStr);
        jsonElement.jsonValue=new HashMap<>();
        HashMap<String,String> hashMapObjs=getJsonObjs(_JsonStr);
        hashMapObjs.forEach((S,V)->
        {
            JsonElement je=new JsonElement();
            je.rootTag=S;
            je.parentElement=jsonElement;
            jsonElement.jsonValue.putIfAbsent(S,parsingBody(je,V));
        });


        jsonElement.boolsValue=getBoolMap(_JsonStr);
        jsonElement.intsValue=getIntMap(_JsonStr);
        jsonElement.doublesValue=getDoubleMap(_JsonStr);
        jsonElement.stringsValue=getStringMap(_JsonStr);
        jsonElement.jsonsValue=new HashMap<>();
        HashMap<String,List<String>> hashMapArrays=getJsonArrays(_JsonStr);
        hashMapArrays.forEach((S,V)->
        {
            List<JsonElement> listje=new ArrayList<>();
            V.forEach((_json)->
            {
                JsonElement je=new JsonElement();
                je.rootTag=S;
                je.parentElement=jsonElement;
                listje.add(parsingBody(je,_json));
            });
            jsonElement.jsonsValue.putIfAbsent(S,listje);
        });

        return jsonElement;
    }
    //endregion

    public class JsonElement {
        //region 值类型 HashMap<键, 值>
        public HashMap<String, String> stringValue;     // 字符串集合
        public HashMap<String, Integer> intValue;       // 整数集合
        public HashMap<String, Double> doubleValue;       // 浮点集合
        public HashMap<String, Boolean> boolValue;      // 开关集合
        public HashMap<String, JsonElement> jsonValue;  // JsonElement 对象集合
        //endregion

        //region 数组类型 HashMap<键, List<类型>>   List<类型>：值
        public HashMap<String, List<String>> stringsValue;    //字符串数组集合
        public HashMap<String, List<Integer>> intsValue;      // 整数数组集合
        public HashMap<String, List<Double>> doublesValue;      // 浮点数组集合
        public HashMap<String, List<Boolean>> boolsValue;     // 开关数组集合
        public HashMap<String, List<JsonElement>> jsonsValue; // JsonElement对象数组集合
        //endregion

        //region 属性
        public String rootTag;           // 元素根节点名称
        public JsonElement parentElement;// 父节点
        //endregion
    }
}